/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sd.chat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

/**
 *
 * @author Old
 */
public class FBManager extends Thread {

    private ServerManager myManager;
    private Logger log = new Logger(true);
    private boolean mustRun = true;
    private int status = 0;
    private ArrayList<OAuthRequest> todos = new ArrayList<OAuthRequest>();
    private ArrayList<Integer> todosIds = new ArrayList<Integer>();
    private ArrayList<Integer> tipos = new ArrayList<Integer>();
    private OAuthService service;
    private String apiKey = "472855519424204";
    private String apiSecret = "0ead12b561e6da04866711048fc08d0b";
    private Token accessToken;
    private static final String NETWORK_NAME = "Facebook";
    private static final Token EMPTY_TOKEN = null;
    private String codeFromWeb = "";
    private Date lastDate;
    //private JSONParser parser;

    public FBManager(ServerManager myManager) {
        this.myManager = myManager;
        service = new ServiceBuilder().provider(FacebookApi.class).apiKey(apiKey).apiSecret(apiSecret).callback("http://eden.dei.uc.pt/~amaf/echo.php").scope("user_status").build();
        //parser = new JSONParser();
        lastDate = new Date();
    }

    @Override
    public void run() {
        while (mustRun) {
            manageFB();
        }
        log.outln("FBManager terminating...");
    }

    public synchronized boolean isMustRun() {
        return mustRun;
    }

    public synchronized void setMustRun(boolean mustRun) {
        this.mustRun = mustRun;
    }

    public synchronized void manageFB() {
        if (todos.isEmpty()) {
            try {
                log.outln("ClientManager preparint to wait.");
                wait(2000);
            } catch (InterruptedException e) {
                log.erro("interruptedException caught");
            }
        }
        if (status == 0) {
            String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
            codeFromWeb = "";
            myManager.setFBURL(authorizationUrl);
            myManager.setFBStatus("need code from url");
            status = 1;
        } else if (status == 1) {
            if (!codeFromWeb.equals("")) {
                Verifier verifier = new Verifier(codeFromWeb);
                accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
                myManager.setFBStatus("getting access token");
                status = 2;
            }
        } else if (status == 2) {
            myManager.setFBStatus("authenticated");
            status = 3;
        } else if (status == 3) {
            if (!todos.isEmpty()) {
                OAuthRequest request = todos.remove(0);
                int subjectId = todosIds.remove(0);
                int tipo = tipos.remove(0);
                service.signRequest(accessToken, request);
                Response response = request.send();
                try {
                    String resposta = response.getBody();
                    if (tipo == 0) {

                        //JSONObject obj = (JSONObject)JSONValue.parse(response.getBody());
                        if (resposta.indexOf("id") >= 0) {
                            String[] resps = resposta.split(":");
                            String idStr = resps[1].substring(resps[1].indexOf("\"") + 1, resps[1].lastIndexOf("\""));
                            myManager.setPostFBID(subjectId, idStr);
                            log.outln("FBManager post created id: " + idStr);
                        } else {
                            status = 0;
                        }
                    } else if (tipo == 1) {
                        //JSONObject obj = (JSONObject)JSONValue.parse(response.getBody());
                        if (resposta.indexOf("id") >= 0) {
                            String[] resps = resposta.split(":");
                            String idStr = resps[1].substring(resps[1].indexOf("\"") + 1, resps[1].lastIndexOf("\""));
                            myManager.setCommentFBID(subjectId, idStr);
                            log.outln("FBManager comment created id: " + idStr);
                        } else {
                            status = 0;
                        }
                    } else if (tipo == 2) {
                    }
                } catch (IndexOutOfBoundsException err) {
                    log.erro("FBManager parse error");
                }
                //System.out.println(response.getCode());
                //System.out.println(response.getBody());
                log.outln("FBManager got message: " + response.getBody());
                lastDate = new Date();
            }

            //check for new posts
            OAuthRequest requestNewPost = new OAuthRequest(Verb.GET, "https://graph.facebook.com/me/feed");
            //requestNewPost.addBodyParameter("message", "Post by app");
            service.signRequest(accessToken, requestNewPost);
            Response response1 = requestNewPost.send();
            Object obj = JSONValue.parse("["+response1.getBody()+"]");
            JSONArray array=(JSONArray)obj;
            JSONObject jobj = (JSONObject)array.get(0);
            JSONArray fullarr = (JSONArray)jobj.get("data");
            
            for(int i=0; i<fullarr.size(); i++){
                JSONObject jobjdata = (JSONObject)fullarr.get(i);
                if(jobjdata.containsKey("message")){
                    //System.out.println(jobjdata.get("message"));
                    Date data = new Date();
                    try {
                        data = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSSS").parse((String)jobjdata.get("created_time"));
                        //System.out.println(data);
                        if(lastDate.before(data)){
                            System.out.println("fb nova: "+jobjdata.get("message"));
                            Post newFBPost = new Post((String)jobjdata.get("message"), i, new Utilizador("Facebook", "face", 999));
                            newFBPost.setFbId((String)jobjdata.get("id"));
                            myManager.newPost(newFBPost);
                            lastDate = data;
                        }
                    } catch (ParseException ex) {
                        
                    }
                }
            }
            

            //System.out.println(fullarr);
        }
    }

    public synchronized void setAddPostToFB(Post post) {
        OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/me/feed");
        request.addBodyParameter("message", post.getText());
        todos.add(request);
        todosIds.add(post.getId());
        tipos.add(0);
    }

    public synchronized void setAddCommentToFB(Post post, Comment com) {
        OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/" + post.getFbId() + "/comments");
        request.addBodyParameter("message", com.getText());
        todos.add(request);
        todosIds.add(com.getId());
        tipos.add(1);
    }

    public synchronized void setDeletePostToFB(Post post) {
        OAuthRequest request = new OAuthRequest(Verb.DELETE, "https://graph.facebook.com/" + post.getFbId());
        todos.add(request);
        todosIds.add(0);
        tipos.add(2);
    }

    public synchronized void setDeleteCommentToFB(Comment com) {
        OAuthRequest request = new OAuthRequest(Verb.DELETE, "https://graph.facebook.com/" + com.getFbId());
        todos.add(request);
        todosIds.add(0);
        tipos.add(2);
    }

    public synchronized String getCodeFromWeb() {
        return codeFromWeb;
    }

    public synchronized void setCodeFromWeb(String codeFromWeb) {
        this.codeFromWeb = codeFromWeb;
    }
}